from google.appengine.dist import use_library
use_library('django', '1.2')

import cgi
import datetime
from django.utils import simplejson as json
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import channel
import os
import random
import logging

import common
import observer

from model import *
import form

from utils import str_is_not_blank
import story


PLANNING_ROOM = "global"

class MainHandler(common.BaseRequestHandler):
    def get(self, page_name):
        if not Member.is_user_valid():
            if not os.environ['PATH_INFO'] == '/_projects':
                self.redirect('/_projects')
        else:
            try:
                page_path = '/' + page_name
                page_path += ('?' + self.request.query_string if self.request.query_string else '')
                
                iterations = []
                id_it = self.request.get('id_it')
                id_project = ''
                if str_is_not_blank(id_it):
                    iteration = Iteration.get_by_id(long(id_it))
                    id_project = iteration.get_project().key()
                    iterations.append(iteration)
                else:
                    projects = [p for p in Project.get_projects()]
                    id_project = projects[0].key() if projects else 'default'
                    for project in projects:
                        iterations = iterations + list(project.get_active_iterations())

                token = self.create_channel(id_project)
                channel_name = common.get_channel_name(users.get_current_user().user_id())
                online_users = common.get_online_users(channel_name)
                self.write_out('index.html', {
                              'iterations': iterations,
                              'token': token,
                              'online_users': online_users,
                              'events'    : Event.events(),
                              'page': page_path
                              })
            except AttributeError:
                self.response.out.write("Bad id!!!, your id is not correct.")
                logging.exception("Bad id!!!, your id is not correct.")
            except Exception:
                self.response.out.write("Something is wrong, we will try to figure out it.")
                logging.exception("Something is wrong, we will try to figure out it.")
    
    def create_channel(self, id_project):
        user = users.get_current_user()
        common.set_channel_name(user.user_id(), common.CHANNEL_NAME + str(id_project))
        channel_id = user.user_id() + '_' + str(random.randint(1, 10000))
        token = channel.create_channel(channel_id)
        observable = observer.Observable(common.get_channel_name(user.user_id()))
        observable.add_observer({user.nickname(): channel_id})
        common.set_channel_user(channel_id, user.nickname(), common.get_channel_name(user.user_id()))
        return token

class ChatHandler(observer.Observer):
    def _post(self):
        self.update(self.get_response())
    def get_response(self):
        text = self.request.get('message')
        response = {'event': 'chat',
            'args': {'message': text,
            'user': users.get_current_user().nickname()}}
        return self.json_format(response)


class ProjectHandler(common.BaseRequestHandler):
    def _get(self):
        projects = Project.all().run()
        self.write_out('projects_.html', {
                      'projects': projects
                      })
    def _post(self):
        projects = Project.all().run()
        html = self.generate('projects.html', {
                            'projects': projects
                            })
        self.json_response(html)

class IterationHandler(common.BaseRequestHandler):
    def _post(self):
        project_id = self.request.get('project_id')
        project = Project.get_by_id(int(project_id))
        if project.is_user_valid():
            html = self.generate('iterations.html', {
                          'project': project
                          })
            self.json_response(html)
        else:
            
            logging.info('not ... allowed.............................')
            self.not_allowed_error()

class IterationForm(common.BaseRequestHandler):
    def _get(self):
        id = self.request.get('id')
        project_id = ''
        project = None
        iteration_form = None
        if str_is_not_blank(id):
            iteration = Iteration.get_by_id(int(id))
            project_id = iteration.project.key().id()
            project = iteration.get_project()
            iteration_form = form.IterationForm(instance=iteration)
        else:
            project_id = self.request.get('project_id')
            project = Project.get_by_id(int(project_id))
            project_id = project.key().id()
            iteration_form = form.IterationForm()

        if project.is_user_valid():
            html = self.generate('iteration_form.html', {
                                 'project': project,
                                 'iteration_id': id,
                                 'form': iteration_form
                                 })
            self.json_response(html)
        else:
            self.not_allowed_error()

    def _post(self):
        id = self.request.get('id')
        data = None
        if str_is_not_blank(id):
            iteration = Iteration.get_by_id(int(id))
            data = form.IterationForm(data=self.request.POST, instance=iteration)
        else:
            data = form.IterationForm(data=self.request.POST)

        project_id = self.request.get('project_id')
        if data.is_valid():
            iteration = data.save(commit=False)
            if not str_is_not_blank(id):
                project = Project.get_by_id(int(project_id))
                iteration.project = project
                iteration.opened_by = users.get_current_user()
                iteration.put()
                iteration.date = datetime.datetime.now()
            
            iteration.put()
            html = self.generate('iteration_row.html', {'iteration': iteration})
            self.json_response({'result': 'ok', 'html': html})
        else:
            project = Project.get_by_id(int(project_id))
            html = self.generate('iteration_form.html', {
                                 'project': project,
                                 'iteration_id': id,
                                 'form': data
                                 })
            self.json_response({'result': 'error', 'html': html})

class ProjectBacklogHandler(common.BaseRequestHandler):
    def _post(self):
        id = self.request.get('id')
        project_backlog = ProjectBacklog.get_by_id(int(id))
        if  project_backlog.get_project().is_user_valid():
            html = self.generate('project_backlog.html', {
                          'project_backlog': project_backlog
                          })
            self.json_response(html)
        else:
            logging.info('not allll')
            self.not_allowed_error()

class StoryForm(observer.Observer):
    def _get(self):
        id = self.request.get('id')
        if not str_is_not_blank(id) or common.acquire_lock(id):
            iteration_id = ''
            storyForm = None
            iteration = None
            if str_is_not_blank(id):
                story = Story.get_by_id(int(id))
                iteration = story.story_container
                storyForm = form.StoryForm(instance=story)
            else:
                storyForm = form.StoryForm()
                iteration_id = self.request.get('iteration_id')
                iteration = Iteration.get_by_id(int(iteration_id))
                
            if iteration.get_project().is_user_valid():
                html = self.generate('story_form.html', {
                                     'iteration': iteration,
                                     'story_id': id,
                                     'form': storyForm
                                     })
                self.json_response(html)
            else:
                self.not_allowed_error()
        else:
            self.block_error()

    def _post(self):
        id = self.request.get('id')
        if not str_is_not_blank(id) or common.acquire_lock(id):
            data = None
            iteration = None
            iteration_id = ''
            if str_is_not_blank(id):
                self.story = Story.get_by_id(int(id))
                iteration = self.story.story_container
                data = form.StoryForm(data=self.request.POST, instance=self.story)
            else:
                data = form.StoryForm(data=self.request.POST)
                iteration_id = self.request.get('iteration_id')
                iteration = Iteration.get_by_id(int(iteration_id))

            if data.is_valid():
                self.story = data.save(commit=False)
                if not str_is_not_blank(id):
                    iteration = Iteration.get_by_id(int(iteration_id))
                    self.story.story_container = iteration
                    self.story.opened_by = users.get_current_user()
                member_id = self.request.get('assigned_to')
                member = Member.get_by_id(int(member_id))
                self.story.assigned_to = member.user
                self.story.put()
                common.release_lock(self.story.key().id())
                resp = self.request.get('response')
                html = self.generate('%s.html' % resp, {'story': self.story})
                self.json_response({'result': 'ok', 
                                   'html': html,
                                   'id': self.story.key().id()})
            else:
                html = self.generate('story_form.html', {
                                     'iteration': iteration,
                                     'story_id': id,
                                     'form': data
                                     })
                self.json_response({'result': 'error', 'html': html})
        else:
            self.block_error()

class SignupForm(common.BaseRequestHandler):
    def _get(self):
        projects = Project.all().run()
        self.write_out('signupForm.html', {'projects': projects})

    def post(self):
        id_project = self.request.get('id_project')
        project = Project.get_by_id(long(id_project))
        member = Member.get_current_member()
        if not member:
            member = Member(user=users.get_current_user())
            member.put()
        query = ProjectMember.all()
        query.filter('project =', project)
        query.filter('member =', member)
        pm = query.get()
        if not pm:
            pm = ProjectMember(member=member, project=project)
            pm.put()

        self.json_response({ 'id_project': id_project, 'status':pm.status })

class SignupMessageHandler(common.BaseRequestHandler):
    def _get(self):
        self.write_out('sent_signup_request.html', {})

class StoryHandler(common.BaseRequestHandler):
    def _post(self):
        story_id = self.request.get('id')
        _story = Story.get_by_id(int(story_id))
        html = self.generate('story.html', {'story': _story})
        self.json_response(html)


class SupportHistoryForm(webapp.RequestHandler):
    def post(self):
        story_id = self.request.get('id')
        story = Story.get_by_id(int(story_id))
        histories = []
        for justification in story.justifications:
            histories.append({'user':justification.author.nickname(), 'text':justification.text})
            
        response = {'history': histories}
        jsonr = json.dumps(response)
        self.response.headers.add_header('content-type', 'application/json', charset='utf-8')
        self.response.out.write(jsonr)

class ChangeIterationStatus(webapp.RequestHandler):
    def post(self):
        iteration_id = self.request.get('iteration_id')
        iteration = Iteration.get_by_id(int(iteration_id))
        status = self.request.get('status')
        iteration.status = status
        iteration.put()
        response = {'status': iteration.status, 'id': iteration_id}
        jsonr = json.dumps(response)
        self.response.headers.add_header('content-type', 'application/json', charset='utf-8')
        self.response.out.write(jsonr)

application = webapp.WSGIApplication(
                                     [
                                     ('/_projects', ProjectHandler),
                                     ('/iteration_form', IterationForm),
                                     ('/signup', SignupForm),
                                     ('/sent_signup_request', SignupMessageHandler),
                                     ('/edit_description', story.EditStoryDescription),
                                     ('/change_story_status', story.ChangeStoryStatus),
                                     ('/reopen_story', story.ReopenStory),
                                     ('/postpone_story', story.PostponeStoryHandler),
                                     ('/get_support_history', SupportHistoryForm),
                                     ('/change_iteration_status', ChangeIterationStatus),
                                     ('/global_chat', ChatHandler),
#                                     ('/calendar_events', planning.EventsPage),
                                     ('/(.*)', MainHandler),
                                     ],
                                     debug=True)

def main():
    run_wsgi_app(application)

if __name__ == "__main__":
    main()
